package com.zhang.map;

import java.util.Objects;

/**
 * @author 张吉鑫
 * @Description 实现链表哈希映射
 * @date 2021/4/4 17:40
 */
public class LinkedHashMap<K,V> extends HashMap<K,V> {
    private LinkedNode<K,V> first;
    private LinkedNode<K,V> last;


    @Override
    public boolean containsValue(V value) {
        LinkedNode<K,V> node = first;
        while (node != null){
            if (Objects.equals(value, node.value)){
                return true;
            }
            node = node.next;
        }
        return false;
    }

    @Override
    protected void afterRemove(Node<K, V> willNode, Node<K, V> removeNode) {
        LinkedNode<K,V> n1 = (LinkedNode<K, V>) willNode;
        LinkedNode<K,V> n2 = (LinkedNode<K, V>) removeNode;
        if (n1 != n2){
            LinkedNode<K, V> temp = n1.prev;
            n1.prev = n2.prev;
            n2.prev = temp;
            if (n1.prev == null){
                first = n1;
            }else {
                n1.prev.next = n1;
            }

            if (n2.prev == null){
                first = n2;
            }else {
                n2.prev.next = n2;
            }

            LinkedNode<K, V> next = n1.next;
            n1.next = n2.next;
            n2.next = next;
            if (n1.next == null){
                last = n1;
            }else {
                n1.next.prev = n1;
            }

            if (n2.next == null){
                last = n2;
            }else {
                n2.next.prev = n2;
            }
        }
        LinkedNode<K, V> prev = n2.prev;
        LinkedNode<K, V> next = n2.next;
        if (prev == null){
            first = next;
        }else {
            prev.next = next;
        }

        if (next == null){
            last = prev;
        }else {
            next.prev = prev;
        }

        super.afterRemove(willNode, removeNode);
    }

    @Override
    public void traversal(Visitor visitor) {
        if (visitor == null){
            return;
        }
        LinkedNode<K,V> node = first;
        while (node != null){
            if (visitor.visit(node.key, node.value)){
                return;
            }
            node = node.next;
        }
    }

    @Override
    protected Node<K, V> createNode(K key, V value, Node<K, V> parent) {
        LinkedNode<K, V> linkedNode = new LinkedNode<>(key, value, parent);
        if (first == null){
            first = last = linkedNode;
        }else {
            last.next = linkedNode;
            linkedNode.prev = last;
            last = linkedNode;
        }
        return linkedNode;
    }

    private static class LinkedNode<K,V> extends Node<K,V>{
        LinkedNode<K,V> prev;
        LinkedNode<K,V> next;

        public LinkedNode(K key, V value, Node parent) {
            super(key, value, parent);
        }
    }
}
